package com.xbchzh.clifford.utils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;



/**
 * 获取access_token
 * 获取jsapi_ticket
 * 签名signature
 * @author David Huang
 * 参考互联网
 *
 * 1、为了保密appsecrect，第三方需要一个access_token获取和刷新的中控服务器。而其他业务逻辑服务器所使用的access_token均来自于该中控服务器，不应该各自去刷新，否则会造成access_token覆盖而影响业务；
 * 2、目前access_token的有效期通过返回的expire_in来传达，目前是7200秒之内的值。中控服务器需要根据这个有效时间提前去刷新新access_token。在刷新过程中，中控服务器对外输出的依然是老access_token，此时公众平台后台会保证在刷新短时间内，新老access_token都可用，这保证了第三方业务的平滑过渡；
 * 3、access_token的有效时间可能会在未来有调整，所以中控服务器不仅需要内部定时主动刷新，还需要提供被动刷新access_token的接口，这样便于业务服务器在API调用获知access_token已超时的情况下，可以触发access_token的刷新流程。
 *
 *
 * 我把WxConfigBean设计成单例模式啦
 * 但是多线程会不会有问题呀。。。。。还是要在application中放一个WxconfigBean，使用的时候都在application中拿吧
 */

public class WxConfigBean {

	public static String appId = "wx54997e60731bc0cf";
	public static String AppSecret = "2b844786beff67bd11d9088207c519bb";
	
	public String access_token;
	public String jsapi_ticket;

	public String debug;
	public String timestamp;//生成签名的时间戳
	public String nonceStr;//生成签名的随机串
	public String signature;// 签名
	public String jsApiList;// 在初始化赋值，需要使用的JS接口列表

	public long getTime;// 获取时刻
	public long tickTime;// 有效期

	private WxConfigBean() {
		debug = "true";
		tickTime = 7200;
		getTime = 0;
		jsApiList = "[\"onMenuShareTimeline\",\"onMenuShareAppMessage\",\"onMenuShareQQ\",\"chooseImage\",\"previewImage\",\"uploadImage\",\"downloadImage\",\"scanQRCode\"]";
	}
	
	private static WxConfigBean mBean = null; 
	
	public static WxConfigBean getWxConfigBean(){
		if(mBean==null){
			mBean = new WxConfigBean();
		}
		return mBean;
	}

	public void updata(String p_url) {
		long now = System.currentTimeMillis() / 1000;
		if(getTime == 0){
			getTime = now;
			doUpdata();
		}else if((now - getTime)>=tickTime){
			getTime = now;
			doUpdata();
		}
		if(!"NULL".equals(p_url))
			reValue(p_url);
	}

	private void reValue(String p_url) {
		//生成签名的随机串
		nonceStr = create_nonce_str();
		//生成签名的时间戳
		timestamp = create_timestamp();
		//签名
		String str;
        //注意这里参数名必须全部小写，且必须有序
        str = "jsapi_ticket=" + jsapi_ticket +
                  "&noncestr=" + nonceStr +
                  "&timestamp=" + timestamp +
                  "&url=" + p_url;
        try {
			MessageDigest crypt = MessageDigest.getInstance("SHA-1");
			crypt.reset();
            crypt.update(str.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
	}
	private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
	private String create_timestamp() {
		return Long.toString(System.currentTimeMillis() / 1000);
	}

	private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

	private void doUpdata() {
		//1 获取access_token
		access_token = getAccess_token(appId,AppSecret);
		System.out.println("access_token:"+access_token);
		//2 获取jsapi_ticket
		jsapi_ticket = getJsapi_ticket(access_token);
		System.out.println("jsapi_ticket:"+jsapi_ticket);
	}

	private String getJsapi_ticket(String p_access_token) {
		//主要url
		String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	    String requestUrl = url.replace("ACCESS_TOKEN", p_access_token);
	    String jsapi_ticketstr = "";
        try {
        	jsapi_ticketstr = HttpUtils.sendGet(requestUrl);
		} catch (Exception e) {
			e.printStackTrace();
		}
        JSONObject object = JSON.parseObject(jsapi_ticketstr);
        return (String) object.get("ticket");
	}

	private String getAccess_token(String p_appId, String p_appSecret) {
		//凭证获取(GET)
        String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
        String requestUrl = token_url.replace("APPID", p_appId).replace("APPSECRET", p_appSecret);
        String tokenstr = "";
        try {
			tokenstr = HttpUtils.sendGet(requestUrl);
		} catch (Exception e) {
			e.printStackTrace();
		}
        JSONObject object = JSON.parseObject(tokenstr);
        return (String) object.get("access_token");
	}

	public String getAccess_token() {
		return access_token;
	}

	public void setAccess_token(String access_token) {
		this.access_token = access_token;
	}

	public String getJsapi_ticket() {
		return jsapi_ticket;
	}

	public void setJsapi_ticket(String jsapi_ticket) {
		this.jsapi_ticket = jsapi_ticket;
	}

	public String getDebug() {
		return debug;
	}

	public void setDebug(String debug) {
		this.debug = debug;
	}

	public String getTimestamp() {
		return timestamp;
	}

	public void setTimestamp(String timestamp) {
		this.timestamp = timestamp;
	}

	public String getNonceStr() {
		return nonceStr;
	}

	public void setNonceStr(String nonceStr) {
		this.nonceStr = nonceStr;
	}

	public String getSignature() {
		return signature;
	}

	public void setSignature(String signature) {
		this.signature = signature;
	}

	public String getJsApiList() {
		return jsApiList;
	}

	public void setJsApiList(String jsApiList) {
		this.jsApiList = jsApiList;
	}

	public long getGetTime() {
		return getTime;
	}

	public void setGetTime(long getTime) {
		this.getTime = getTime;
	}

	public long getTickTime() {
		return tickTime;
	}

	public void setTickTime(long tickTime) {
		this.tickTime = tickTime;
	}
	
	
	

}
